/***************************************************
*		 Copyright (c) 2018 MINE 田宇
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
***************************************************/

#ifndef __ELF_H__

#define __ELF_H__

#define EI_MAG0			0
#define EI_MAG1			1
#define EI_MAG2			2
#define EI_MAG3			3
#define EI_CLASS		4
#define EI_DATA			5
#define EI_VERSION		6
#define EI_OSABI		7
#define EI_ABIVERSION	8
#define EI_PAD			9

#define EI_NIDENT		16

typedef struct
{
    unsigned char	e_ident[EI_NIDENT];    /* Id bytes */
    unsigned short	e_type;            /* file type */
    unsigned short	e_machine;        /* machine type */
    unsigned int	e_version;        /* version number */
    unsigned long	e_entry;        /* entry point */
    long			e_phoff;        /* Program hdr offset */
    long			e_shoff;        /* Section hdr offset */
    unsigned int	e_flags;        /* Processor flags */
    unsigned short	e_ehsize;        /* sizeof ehdr */
    unsigned short	e_phentsize;        /* Program header entry size */
    unsigned short	e_phnum;        /* Number of program headers */
    unsigned short	e_shentsize;        /* Section header entry size */
    unsigned short	e_shnum;        /* Number of section headers */
    unsigned short	e_shstrndx;        /* String table index */
}Elf64_Ehdr;

typedef struct
{
    unsigned int	p_type;        /* entry type */
    unsigned int	p_flags;    /* flags */
    long			p_offset;    /* offset */
    unsigned long	p_vaddr;    /* virtual address */
    unsigned long	p_paddr;    /* physical address */
    unsigned long	p_filesz;    /* file size */
    unsigned long	p_memsz;    /* memory size */
    unsigned long	p_align;    /* memory & file alignment */
}Elf64_Phdr;

typedef struct
{
    unsigned int	sh_name;    /* section name */
    unsigned int	sh_type;    /* section type */
    unsigned long	sh_flags;    /* section flags */
    unsigned long	sh_addr;    /* virtual address */
    long			sh_offset;    /* file offset */
    unsigned long	sh_size;    /* section size */
    unsigned int	sh_link;    /* link to another */
    unsigned int	sh_info;    /* misc info */
    unsigned long	sh_addralign;    /* memory alignment */
    unsigned long	sh_entsize;    /* table entry size */
}Elf64_Shdr;

/* sh_type */
#define SHT_NULL	0
#define SHT_PROGBITS	1
#define SHT_SYMTAB	2
#define SHT_STRTAB	3
#define SHT_RELA	4
#define SHT_HASH	5
#define SHT_DYNAMIC	6
#define SHT_NOTE	7
#define SHT_NOBITS	8
#define SHT_REL		9
#define SHT_SHLIB	10
#define SHT_DYNSYM	11
#define SHT_NUM		12
#define SHT_LOPROC	0x70000000
#define SHT_HIPROC	0x7fffffff
#define SHT_LOUSER	0x80000000
#define SHT_HIUSER	0xffffffff

typedef struct
{
    unsigned int	st_name;    /* Symbol name index in str table */
    unsigned char	st_info;    /* type / binding attrs */
    unsigned char	st_other;    /* unused */
    unsigned short	st_shndx;    /* section index of symbol */
    unsigned long	st_value;    /* value of symbol */
    unsigned long	st_size;    /* size of symbol */
}Elf64_Sym;

typedef struct
{
    unsigned long	r_offset;    /* where to do it */
    unsigned long	r_info;        /* index & type of relocation */
}Elf64_Rel;

typedef struct
{
    unsigned long	r_offset;    /* where to do it */
    unsigned long	r_info;        /* index & type of relocation */
    long			r_addend;    /* adjustment value */
}Elf64_Rela;

#define R_X86_64_NONE		0	/* No reloc */
#define R_X86_64_64			1	/* Direct 64 bit  */
#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
#define R_X86_64_PLT32		4	/* 32 bit PLT address */
#define R_X86_64_COPY		5	/* Copy symbol at runtime */
#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
#define R_X86_64_RELATIVE	8	/* Adjust by program base */
#define R_X86_64_GOTPCREL	9	/* 32 bit signed pc relative offset to GOT */
#define R_X86_64_32			10	/* Direct 32 bit zero extended */
#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
#define R_X86_64_16			12	/* Direct 16 bit zero extended */
#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
#define R_X86_64_8			14	/* Direct 8 bit sign extended  */
#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
#define R_X86_64_DTPMOD64	16
#define R_X86_64_DTPOFF64	17
#define R_X86_64_TPOFF64	18
#define R_X86_64_TLSGD		19
#define R_X86_64_TLSLD		20
#define R_X86_64_DTPOFF32	21
#define R_X86_64_GOTTPOFF	22
#define R_X86_64_TPOFF32	23
#define R_X86_64_PC64		24
#define R_X86_64_GOTOFF64	25
#define R_X86_64_GOTPC32	26
#define R_X86_64_SIZE32		32
#define R_X86_64_SIZE64		33
#define R_X86_64_GOTPC32_TLSDESC	34
#define R_X86_64_TLSDESC_CALL		35
#define R_X86_64_TLSDESC			36
#define R_X86_64_IRELATIVE			37


#endif
